import { ExecutionContext, Injectable, Req } from '@nestjs/common';
import { CreateLogDto } from './dto/create-log.dto';
import { UpdateLogDto } from './dto/update-log.dto';
import { Core } from 'src/core';
import { ObjectId } from 'mongodb';
import { PaginationLogDto } from './dto/pagination-log.dto';

@Injectable()
export class LogService {
    create(createLogDto: CreateLogDto, other: Object) {
        // const request:any = context.switchToHttp().getRequest<Request>();

        return this.getCollection().insertOne({
            ...createLogDto,
            ...other,
            createdAt: new Date(),
            updatedAt: new Date(),
        });
    }

    async findAll(paginationLogDto: PaginationLogDto) {
        const param: any = {};
        if (paginationLogDto.username) {
            param.username = { $in: [paginationLogDto.username] };
        }
        // console.log("param=====")
        // console.log(param)
        const limit = +paginationLogDto.limit;
        const page = +paginationLogDto.page;
        const total = await this.getCollection().countDocuments(param); // 获取总用户数
        const totalPages = Math.ceil(total / limit);
        const list = await this.getCollection().find(param).skip((page - 1) * limit).limit(limit).toArray();
        return { list, pagination: { totalPages, page, limit } };
    }

    async findOne(id: string) {
        const ary = await this.getCollection().findOne({ _id: new ObjectId(id) });
        return JSON.stringify(ary);
    }

    async update(id: string, updateLogDto: UpdateLogDto) {
        const filter = { _id: new ObjectId(id) };
        const update = { $set: { ...updateLogDto, updatedAt: new Date() } };
        const result = await this.getCollection().updateOne(filter, update);
        return `Updated ${result.modifiedCount} document(s)`;
    }

    async remove(id: string) {
        const insertResult = await this.getCollection().deleteOne({ _id: new ObjectId(id) });
        return insertResult.deletedCount.toString();
    }
    async getAll4(paginationLogDto: PaginationLogDto) {
        let db = Core.ins.db;
        const mappingCollection = db.collection('log');
        // const videoCollection = db.collection('video');
        // const userCollection = db.collection('user');

        const mappedData = await mappingCollection.aggregate([
            {
                $lookup: {
                    from: 'video',
                    localField: 'videoId',
                    foreignField: '_id',
                    as: 'video'
                }
            },
            {
                $lookup: {
                    from: 'user',
                    localField: 'userId',
                    foreignField: '_id',
                    as: 'user'
                }
            },
            {
                $unwind: {
                    path: '$video',
                    preserveNullAndEmptyArrays: true
                }
            },
            {
                $unwind: {
                    path: '$user',
                    preserveNullAndEmptyArrays: true
                }
            },
            {
                $project: {
                    id: '$_id',
                    ip: '$ip',
                    timer: '$createdAt',
                    video: '$video',
                    user: '$user'
                }
            }
        ]).toArray();

        return mappedData;
    }

    getMatch(username: string) {
        return new Promise(resolve => {
            if (!username) {
                resolve([]);
            }
            let db = Core.ins.db;
            const userCollection = db.collection('user');

            userCollection.findOne({ username }).then(user => {
                if (!user) {
                    console.log('User not found');
                    resolve(null);
                    return;
                }
                console.log("user", user);
                resolve([{ $match: { userId: user._id.toString() } }]);
            });
        })

    }

    getTotal(username: string) {

        return new Promise(resolve => {
            let db = Core.ins.db;
            const logCollection = db.collection('log');
            if (!username) {
                // resolve([]);
                logCollection.countDocuments({})
                    .then(totalCount => {
                        resolve(totalCount);
                    })
                return;
            }

            const userCollection = db.collection('user');

            userCollection.findOne({ username }).then(user => {
                if (!user) {
                    console.log('User not found');
                    resolve(0);
                    return;
                }
                console.log("user", user);
                // resolve([{ $match: { userId: user._id.toString() } }]);
                logCollection.countDocuments({ userId: user._id.toString() })
                    .then(totalCount => {
                        resolve(totalCount);
                    })
            });
        })
    }

    async getAll(paginationLogDto: PaginationLogDto) {
        console.log("paginationLogDto ----", paginationLogDto)
        const username = paginationLogDto.username

        const page = +paginationLogDto.page; // 页码
        const pageSize = +paginationLogDto.limit; // 每页显示的数量
        const sortField = 'createdAt'; // 排序字段
        const sortOrder = -1; // 排序顺序（1为升序，-1为降序）
        const sort = paginationLogDto.sort ? { createdAt: paginationLogDto.sort } : {}

        let db = Core.ins.db;
        /*
        // 获取 video-user 映射表的数据
        const mappingCollection = db.collection('log');
        const mappingData = await mappingCollection.find().toArray();

        // 获取 video 表的数据
        const videoCollection = db.collection('video');
        const videoData = await videoCollection.find().toArray();

        // 获取 user 表的数据
        const userCollection = db.collection('user');
        const userData = await userCollection.find().toArray();

        // 分页参数
        const pageNumber = 1;    // 页数，从 1 开始
        const pageSize = 20;     // 每页的数据条数

        // 计算分页查询的起始索引
        const startIndex = (pageNumber - 1) * pageSize;


        // 进行映射并生成最终数据
        const mappedData = mappingData.map((item) => {
            const video = videoData.find((v) => this.same(v._id, item.videoId));
            const user = userData.find((u) => this.same(u._id, item.userId));
            return {
                id: item._id,
                ip: item.ip,
                timer: item.createdAt,
                video: video,
                user: user
            };
        }).slice(startIndex, startIndex + pageSize);
        */

        // console.log(mappedData)

        const mappingCollection = db.collection('log');
        const videoCollection = db.collection('video');
        const userCollection = db.collection('user');

        let totalCount: any = await this.getTotal(username);
        const totalPages = Math.ceil(totalCount / pageSize);

        const list: any = await this.getMatch(username);
        if (!list) {
            return { list, pagination: { totalPages } };
        }

        const pipe = [
            ...list,
            {
                $lookup: {
                    from: 'video',
                    let: { videoIdStr: '$videoId' },
                    pipeline: [
                        {
                            $match: {
                                $expr: {
                                    $eq: ['$_id', { $toObjectId: '$$videoIdStr' }]
                                }
                            }
                        }
                    ],
                    as: 'video'
                }
            },
            {
                $lookup: {
                    from: 'user',
                    let: { userIdStr: '$userId' },
                    pipeline: [
                        {
                            $match: {
                                $expr: {
                                    $eq: ['$_id', { $toObjectId: '$$userIdStr' }]
                                }
                            }
                        }
                    ],
                    as: 'user'
                }
            },
            {
                $unwind: '$video'
            },
            {
                $unwind: '$user'
            }];

        // paginationLogDto.sort ? { createdAt: paginationLogDto.sort } : {}

        if (paginationLogDto.sort) {
            pipe.push({
                $sort: { createdAt: paginationLogDto.sort }
            });
        }


        pipe.push(...[
            {
                $skip: (page - 1) * pageSize
            },
            {
                $limit: pageSize
            },
            {
                $project: {
                    _id: 0,
                    videoId: 1,
                    userId: 1,
                    video: 1,
                    user: 1,
                    ip: 1,
                    timer: '$createdAt',
                }
            },
        ])



        let result = await mappingCollection.aggregate(pipe).toArray()

        console.log(result); // 输出映射结果

        // return result;
        return { list: result, pagination: { totalPages } }
    }

    same(a: any, b: any) {
        if (typeof a == "string") {
            a = new ObjectId(a);
        }
        if (typeof b == "string") {
            b = new ObjectId(b);
        }
        return a.equals(b);
    }

    async getAll5(paginationLogDto: PaginationLogDto) {
        const pageNumber = 1;    // 頁數，從 1 開始
        const pageSize = 20;     // 每頁的數據條數

        const mappedData = await Core.ins.db.collection("log").aggregate([
            {
                $lookup: {
                    from: 'video',
                    localField: 'videoId',
                    foreignField: '_id',
                    as: 'video'
                }
            },

            {
                $lookup: {
                    from: 'user',
                    localField: 'userId',
                    foreignField: '_id',
                    as: 'user'
                }
            },
            {
                $unwind: {
                    path: '$video',
                    preserveNullAndEmptyArrays: true
                }
            },
            {
                $unwind: {
                    path: '$user',
                    preserveNullAndEmptyArrays: true
                }
            },
            {
                $project: {
                    _id: 1,
                    ip: 1,
                    userId: 1,
                    videoId: 1,
                    video: '$video',
                    user: '$user'
                }
            },
            {
                $skip: (pageNumber - 1) * pageSize
            },
            {
                $limit: pageSize
            }
        ]).toArray();
        console.log(mappedData);
        return mappedData;
    }

    getCollection() {
        return Core.ins.db.collection("log");
    }
}
